NonZero

查找输入张量中 非零元素的位置索引。 该算子按线性顺序遍历输入张量,对于满足“非零”判定条件的元素, 计算其在各维度上的索引,并顺序写入输出索引张量。

对于浮点类型,非零的判定标准为:

\[|x| > \epsilon\]

其中 \(\epsilon\) 为平台定义的极小阈值(如 FLOAT_EPS), 用于避免数值误差导致的误判。

输入:
  • input - 输入数据地址,按一维连续内存存储。

  • dim_strides - 各维度步长数组,长度为 input_rank, 用于将线性索引映射为多维索引。

  • shape - 输入张量的形状数组,长度为 input_rank (当前实现中主要用于描述维度信息)。

  • input_rank - 输入张量的维度数。

  • length - 输入张量的元素总数。

  • core_mask - 核掩码(仅适用于共享存储版本)。

输出:
  • output - 非零元素索引输出地址, 按 [non_zero_num, input_rank] 形式顺序存储。

  • non_zero_num - 非零元素个数指针,函数执行结束后保存最终非零元素数量。

支持平台:

FT78NE MT7004

备注

  • FT78NE 支持 fp32fp64int8int16int32cplx64cplx128 类型

  • MT7004 支持 fp16fp32int16int32cplx64 类型

  • 输出索引按照输入线性遍历顺序排列

  • non_zero_num 在调用前需初始化为 0

共享存储版本:

void fp_nonzero_s(float *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length, int core_mask)
void dp_nonzero_s(double *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length, int core_mask)
void i8_nonzero_s(int8_t *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length, int core_mask)
void i16_nonzero_s(int16_t *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length, int core_mask)
void i32_nonzero_s(int32_t *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length, int core_mask)
void c64_nonzero_s(cplx64 *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length, int core_mask)
void c128_nonzero_s(cplx128 *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length, int core_mask)

C调用示例:

 1// FT78NE 示例
 2#include <stdio.h>
 3#include <nonzero.h>
 4
 5int main(int argc, char* argv[]) {
 6    float *input = (float *)0xA0000000;
 7    int *output = (int *)0xC0000000;
 8    int *non_zero_num = (int *)0xA1000000;
 9    int *dim_strides = (int *)0xA2000000;
10    int *shape = (int *)0xA3000000;
11
12    int input_rank = 3;
13    int length = 1024;
14    int core_mask = 0xff;
15
16    non_zero_num[0] = 0;
17
18    fp_nonzero_s(input, output, non_zero_num,
19                 dim_strides, shape, input_rank,
20                 length, core_mask);
21    return 0;
22}

私有存储版本:

void fp_nonzero_p(float *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length)
void dp_nonzero_p(double *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length)
void i8_nonzero_p(int8_t *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length)
void i16_nonzero_p(int16_t *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length)
void i32_nonzero_p(int32_t *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length)
void c64_nonzero_p(cplx64 *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length)
void c128_nonzero_p(cplx128 *input, int *output, int *non_zero_num, int *dim_strides, int *shape, int input_rank, int length)

C调用示例:

 1// FT78NE 示例
 2#include <stdio.h>
 3#include <nonzero.h>
 4
 5int main(int argc, char* argv[]) {
 6    float *input = (float *)0x10810000;   // L2 空间
 7    int *output = (int *)0x10820000;
 8    int *non_zero_num = (int *)0x10830000;
 9    int *dim_strides = (int *)0x10840000;
10    int *shape = (int *)0x10850000;
11
12    int input_rank = 3;
13    int length = 1024;
14
15    non_zero_num[0] = 0;
16
17    fp_nonzero_p(input, output, non_zero_num,
18                 dim_strides, shape, input_rank, length);
19    return 0;
20}